﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics.Contracts;
using Kooboo.Commerce.Exceptions;
using Kooboo.Collections;
using System.ComponentModel.Composition;

namespace Kooboo.Commerce.Repositories
{
    [Export(typeof(ICartRepository))]
    public partial class EntityRepositories : ICartRepository
    {
        #region Cart

        public IQueryable<ICart> Carts
        {
            get
            {
                return this.DataReaderContext.Carts;
            }
        }

        public void Post(ICart cart)
        {
            Contract.Requires(cart != null);

            var item = new Cart();

            item.CreateDate = cart.CreateDate;
            item.Address1 = cart.Address1;
            item.Address2 = cart.Address2;
            item.City = cart.City;
            item.Country = cart.Country;
            item.Coupon = cart.Coupon;


            item.FirstName = cart.FirstName;
            item.InsuredAmount = cart.InsuredAmount;
            item.InvoiceAddress1 = cart.InvoiceAddress1;
            item.InvoiceAddress2 = cart.InvoiceAddress2;
            item.InvoiceCity = cart.InvoiceCity;

            item.InvoiceCountry = cart.InvoiceCountry;

            item.InvoiceFirstName = cart.InvoiceFirstName;
            item.InvoiceLastName = cart.InvoiceLastName;
            item.InvoicePhone = cart.InvoicePhone;
            item.InvoicePostcode = cart.InvoicePostcode;
            item.InvoiceState = cart.InvoiceState;
            item.UseInvoiceAddress = cart.UseInvoiceAddress;

            item.LastName = cart.LastName;

            item.Discount = cart.Discount;
            //OrderStatus = (int)OrderStatus.Shopping;
            item.PaymentMethodCost = cart.PaymentMethodCost;
            item.PaymentName = cart.Payment==null?null: cart.Payment.MethodName;
            item.Phone = cart.Phone;
            item.Postcode = cart.Postcode;
            item.Remark = cart.Remark;
            if (cart.Shipping == null)
            {
                item.ShippingId = null;
            }
            else
            {
                item.ShippingId = cart.Shipping.Id;
            }

            item.ShippingCost = cart.ShippingCost;
            item.State = cart.State;
            item.SubTotal = cart.SubTotal;
            item.Total = cart.Total;
            item.TotalDiscount = cart.TotalDiscount;
            item.TotalTaxCost = cart.TotalTaxCost;





            if (cart.Customer == null)
            {
                item.CustomerId = null;
            }
            else
            {
                item.CustomerId = cart.Customer.Id;
            }


            this.DataWriterContext.Carts.InsertOnSubmit(item);
            this.DataWriterContext.SubmitChanges();
            cart.Id = item.Id;


            foreach (var i in cart.CartItems)
            {
                var cartitem = new CartItem()
                {
                    Discount = i.Discount,
                    ProductName = i.ProductName,
                    Quantity = i.Quantity,
                    SKU = i.SKU,
                    SubTotal = i.SubTotal,
                    TaxCost = i.TaxCost,
                    SaleItemId = i.SaleItem.Id,
                    ProductId = i.Product.Id,
                    Total = i.Total
                };

                this.DataWriterContext.CartItems.InsertOnSubmit(cartitem);
                this.DataWriterContext.SubmitChanges();

                i.Id = cartitem.Id;
            }

            this.DataWriterContext.SubmitChanges();
       
        }

        public void Put(ICart cart)
        {
            Contract.Requires(cart != null);

            var item = this.DataWriterContext.Carts
                .Where(i => i.Id == cart.Id)
                .FirstOrDefault();

            if (item == null)
            {
                throw new KeyNotFoundException("Cart: " + cart.Id);

            }

            item.Address1 = cart.Address1;
            item.Address2 = cart.Address2;
            item.City = cart.City;

            item.Country = cart.Country;

            item.Coupon = cart.Coupon;


            item.FirstName = cart.FirstName;
            item.InsuredAmount = cart.InsuredAmount;
            item.InvoiceAddress1 = cart.InvoiceAddress1;
            item.InvoiceAddress2 = cart.InvoiceAddress2;
            item.InvoiceCity = cart.InvoiceCity;
            item.InvoiceCountry = cart.InvoiceCountry;

            item.InvoiceFirstName = cart.InvoiceFirstName;
            item.InvoiceLastName = cart.InvoiceLastName;
            item.InvoicePhone = cart.InvoicePhone;
            item.InvoicePostcode = cart.InvoicePostcode;
            item.InvoiceState = cart.InvoiceState;
            item.LastName = cart.LastName;
            item.Discount = cart.Discount;
            //item.OrderStatus = (int)OrderStatus.Shopping;
            item.PaymentMethodCost = cart.PaymentMethodCost;
            item.PaymentName = cart.Payment == null ? null : cart.Payment.MethodName;
            item.Phone = cart.Phone;
            item.Postcode = cart.Postcode;
            item.Remark = cart.Remark;

            if (cart.Shipping == null)
            {
                item.ShippingId = null;
            }
            else
            {
                item.ShippingId = cart.Shipping.Id;
            }

            item.ShippingCost = cart.ShippingCost;

            item.State = cart.State;
            item.SubTotal = cart.SubTotal;
            item.Total = cart.Total;
            item.TotalDiscount = cart.TotalDiscount;
            item.TotalTaxCost = cart.TotalTaxCost;


            if (cart.Customer == null)
            {
                item.CustomerId = null;
            }
            else
            {
                item.CustomerId = cart.Customer.Id;
            }



            var items = this.DataWriterContext.CartItems.Where(i => i.CartId == cart.Id);
            var result = items.Compare(cart.CartItems, (i1, i2) => i1.Id == i2.Id, (i1, i2) =>
                {
                    i1.Discount = i2.Discount;
                    i1.Product = i2.Product;
                    i1.ProductName = i2.ProductName;
                    //i1.Promotions = i2.Promotions;
                    i1.Quantity = i2.Quantity;
                    i1.SaleItem = i2.SaleItem;
                    i1.SKU = i2.SKU;
                    i1.SubTotal = i2.SubTotal;
                    i1.TaxCost = i2.TaxCost;
                    i1.UnitPrice = i2.UnitPrice;
                    i1.Total = i2.Total;

                });

            foreach (var i in result.Deleted)
            {
                this.DataWriterContext.CartItems.DeleteOnSubmit((CartItem)i);
            }
            this.DataWriterContext.SubmitChanges();

            foreach (var i in result.Added)
            {
                var cartitem = new CartItem()
                {
                    Discount = i.Discount,
                    ProductName = i.ProductName,
                    Quantity = i.Quantity,
                    SKU = i.SKU,
                    SubTotal = i.SubTotal,
                    TaxCost = i.TaxCost,
                    SaleItemId = i.SaleItem.Id,
                    ProductId = i.Product.Id,
                    Total = i.Total
                };

                
                cartitem.CartId = cart.Id;

                this.DataWriterContext.CartItems.InsertOnSubmit(cartitem);
                this.DataWriterContext.SubmitChanges();

                i.Id = cartitem.Id;
            }

            this.DataWriterContext.SubmitChanges();
        }

        public void Delete(ICart cart)
        {
            if (cart != null)
            {
                var item = this.DataWriterContext.Carts
                .Where(i => i.Id == cart.Id)
                .FirstOrDefault();

                if (item != null)
                {
                    this.DataWriterContext.CartItems.DeleteAllOnSubmit(this.DataWriterContext.CartItems.Where(i => i.CartId == item.Id));
                    this.DataWriterContext.Carts.DeleteOnSubmit(item);                    
                    this.DataWriterContext.SubmitChanges();
                }
            }
        }

        #endregion
    }
}
